package com.lzm.ydpt.module.common;

import android.Manifest;
import android.animation.ObjectAnimator;
import android.graphics.Color;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.amap.api.location.AMapLocation;
import com.amap.api.maps2d.AMap;
import com.amap.api.maps2d.CameraUpdateFactory;
import com.amap.api.maps2d.MapView;
import com.amap.api.maps2d.UiSettings;
import com.amap.api.maps2d.model.BitmapDescriptorFactory;
import com.amap.api.maps2d.model.CameraPosition;
import com.amap.api.maps2d.model.LatLng;
import com.amap.api.maps2d.model.MyLocationStyle;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.byt.framlib.base.BaseActivity;
import com.byt.framlib.baseadapter.rv.RvCommonAdapter;
import com.byt.framlib.baseadapter.rv.RvViewHolder;
import com.byt.framlib.basemap.NETLocationListener;
import com.byt.framlib.basemap.NETLocationManager;
import com.byt.framlib.basemvp.BasePresenter;
import com.byt.framlib.commonutils.GpsUtils;
import com.byt.framlib.commonutils.permission.PermissionReq;
import com.byt.framlib.commonutils.permission.ResultListener;
import com.byt.framlib.commonwidget.ClearableEditText;
import com.byt.framlib.commonwidget.LoadingTip;
import com.byt.framlib.commonwidget.OnNoDoubleClickListener;
import com.byt.framlib.commonwidget.onclicktwo.AntiShake;
import com.lzm.ydpt.R;
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.listener.OnLoadMoreListener;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.OnClick;

/**
 * 地图地址
 */
public class MapAddressActivity extends BaseActivity implements NETLocationListener {
    public static final String INP_POIITEMS_INFO = "POIITEMS_INFO";
    @BindView(R.id.edt_sear_data)
    ClearableEditText ed_search_place;
    @BindView(R.id.mpv_select_address)
    MapView map_select_place;
    @BindView(R.id.srl_place_list)
    SmartRefreshLayout srl_place_list;
    @BindView(R.id.rv_place_list)
    RecyclerView rv_place_list;
    @BindView(R.id.ltp_address_date)
    LoadingTip ltp_address_date;
    @BindView(R.id.img_current_location)
    ImageView img_current_location;
    @BindView(R.id.img_center_location)
    ImageView img_center_location;

    private RvCommonAdapter<PoiItem> mRvAdapter = null;
    private List<PoiItem> mPoiItems = new ArrayList<>();

    private AMap mAMap;
    private UiSettings mUiSettings;
    private PoiSearch mPoiSearch;
    private PoiSearch.Query mQuery;
    private boolean isSearchData = false;//是否搜索地址数据
    private int searchNowPageNum = 1;//当前poi搜索页数
    private float zoom = 18;//地图缩放级别


    private NETLocationManager mManager = null;
    private AMapLocation mLocation = null;

    private onPoiSearchLintener mOnPoiSearchListener;
    private GeocodeSearch.OnGeocodeSearchListener mOnGeocodeSearchListener;

    private ObjectAnimator mTransAnimator;//地图中心标志动态
    private LatLng mLatLng = null;
    private PoiItem selectPoiItem = null;

    @Override
    public int getLayoutId() {
        return R.layout.activity_map_address;
    }

    @Override
    public BasePresenter initPreData() {
        return null;
    }

    @Override
    public void initView() {
        mLatLng = getIntent().getParcelableExtra(INP_POIITEMS_INFO);
        initDatas();
        initAdapter();
        initListener();
        if (mLatLng == null) { // 没有给点需要定位
            startLocation();
        } else {
            getAddressInfoByLatLong(mLatLng.latitude, mLatLng.longitude);
            moveMapCamera(mLatLng.latitude, mLatLng.longitude);
            mAMap.invalidate();
        }
    }

    @OnClick({R.id.tv_map_address_cancal, R.id.tv_map_address_submit})
    public void onClick(View view) {
        if (AntiShake.check(view.getId())) {
            return;
        }
        switch (view.getId()) {
            case R.id.tv_map_address_cancal:
                finish();
                break;
            case R.id.tv_map_address_submit:
                setResultOk();
                break;
        }

    }

    private void initAdapter() {
        rv_place_list.setLayoutManager(new LinearLayoutManager(this));
        mRvAdapter = new RvCommonAdapter<PoiItem>(this, mPoiItems, R.layout.item_location_sign_view) {
            @Override
            protected void convert(RvViewHolder holder, PoiItem poiItem, int position) {
                if (selectPoiItem != null && selectPoiItem.equals(poiItem)) {
                    holder.setSelected(R.id.tv_target_location, true);
                } else if (selectPoiItem == null && position == 0) {
                    holder.setSelected(R.id.tv_target_location, true);
                } else {
                    holder.setSelected(R.id.tv_target_location, false);
                }
                holder.setText(R.id.tv_target_location, poiItem.getTitle());
                holder.setText(R.id.tv_detailed_location, poiItem.getSnippet());
                holder.getConvertView().setOnClickListener(new OnNoDoubleClickListener() {
                    @Override
                    protected void onNoDoubleClick(View v) {
                        try {
                            selectPoiItem = poiItem;
                            isSearchData = false;
                            moveMapCamera(poiItem.getLatLonPoint().getLatitude(), poiItem.getLatLonPoint().getLongitude());
                            mAMap.invalidate();
                            notifyDataSetChanged();
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    }
                });
            }
        };
        rv_place_list.setAdapter(mRvAdapter);
        srl_place_list.setEnableRefresh(false);
        srl_place_list.setOnLoadMoreListener(new OnLoadMoreListener() {
            @Override
            public void onLoadMore(@NonNull RefreshLayout refreshLayout) {
                if (mLatLng != null) {
                    searchNowPageNum++;
                    doSearchQuery(new LatLonPoint(mLatLng.latitude, mLatLng.longitude));
                } else {
                    srl_place_list.finishLoadMore();
                }
            }
        });
        mPoiItems.clear();
    }

    private void initListener() {
        //监测地图画面的移动
        mAMap.setOnCameraChangeListener(new AMap.OnCameraChangeListener() {
            @Override
            public void onCameraChangeFinish(CameraPosition cameraPosition) {
                img_current_location.setSelected(false);
                if (null != mLatLng && null != cameraPosition && isSearchData) {
                    zoom = cameraPosition.zoom;
                    getAddressInfoByLatLong(cameraPosition.target.latitude, cameraPosition.target.longitude);
                    startTransAnimator();
                }
                if (!isSearchData) {
                    isSearchData = true;
                }
            }

            @Override
            public void onCameraChange(CameraPosition cameraPosition) {

            }
        });
        //设置触摸地图监听器
        mAMap.setOnMapClickListener(new AMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {
                isSearchData = true;
            }
        });

        //Poi搜索监听器
        mOnPoiSearchListener = new onPoiSearchLintener();

        //逆地址搜索监听器
        mOnGeocodeSearchListener = new GeocodeSearch.OnGeocodeSearchListener() {
            @Override
            public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
                if (i == 1000) {
                    ltp_address_date.setLoadingTip(LoadingTip.LoadStatus.finish);
                    if (regeocodeResult != null) {
                        if (!mPoiItems.isEmpty()) {
                            mPoiItems.clear();
                        }
                        ltp_address_date.setLoadingTip(LoadingTip.LoadStatus.loading);
                        doSearchQuery(regeocodeResult.getRegeocodeQuery().getPoint());
                    }
                } else {
                    ltp_address_date.setLoadingTip(LoadingTip.LoadStatus.empty);
                }
            }

            @Override
            public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {

            }
        };

        ed_search_place.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                if (null != editable) {
                    if (0 == editable.length()) {//没有输入则清空搜索记录
//                        mPoiItems.clear();
//                        mRvAdapter.notifyDataSetChanged();
                    } else {
                        doSearchQuery(editable.toString(), "", null);
                    }
                }
            }
        });

    }


    @OnClick({R.id.tv_map_address_cancal, R.id.tv_map_address_submit, R.id.img_current_location})
    public void OnClick(View v) {
        if (AntiShake.check(v.getId())) {
            return;
        }
        switch (v.getId()) {
            case R.id.tv_map_address_cancal:
                finish();
                break;
            case R.id.tv_map_address_submit:
                if (selectPoiItem != null) {
                    Bundle bundle = new Bundle();
                    bundle.putParcelable(INP_POIITEMS_INFO, selectPoiItem);
                    setResultOk(bundle);
                }
                break;
            case R.id.img_current_location:
                if (null == mLocation) {
                    startLocation();
                } else {
                    zoom = 18f;
                    searchNowPageNum = 1;
                    doWhenLocationSucess(mLocation.getLatitude(), mLocation.getLongitude());
                }
                break;
        }
    }

    private void initDatas() {
        map_select_place.onCreate(mSavedInstanceState);// 此方法必须重写
        mAMap = map_select_place.getMap();
        mUiSettings = mAMap.getUiSettings();
        mUiSettings.setZoomControlsEnabled(false);//是否显示地图中放大缩小按钮
        mUiSettings.setMyLocationButtonEnabled(false); // 是否显示默认的定位按钮
        mUiSettings.setScaleControlsEnabled(true);//是否显示缩放级别
        mTransAnimator = ObjectAnimator.ofFloat(img_center_location, "translationY", 0f, -80f, 0f);
        mTransAnimator.setDuration(800);
    }

    /**
     * 开始定位
     */
    public void startLocation() {
        PermissionReq.with(this)
                .permissions(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION)
                .result(new ResultListener() {
                    @Override
                    public void onGranted() {
                        if (!GpsUtils.isOPen(mBContext)) {
                            showShortToast("您未开启手机定位服务，请开启GPS");
                            return;
                        }
                        if (mManager == null) {
                            mManager = new NETLocationManager(mBContext, MapAddressActivity.this);
                        }
                        mManager.start();
                    }

                    @Override
                    public void onDenied() {
                        showShortToast("未开启位置权限，无法获取位置");
                    }
                }).request();
    }

    /**
     * 停止定位
     */
    private void stopLocation() {
        if (mManager != null) {
            mManager.onStop();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        map_select_place.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        map_select_place.onPause();
    }

    @Override
    public void onStop() {
        if (mManager != null) {
            mManager.onStop();
        }
        super.onStop();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        map_select_place.onSaveInstanceState(outState);
    }


    @Override
    public void onBackPressed() {
        super.onBackPressed();
        finish();
    }

    @Override
    protected void onDestroy() {
        stopLocation();
        map_select_place.onDestroy();
        if (null != mPoiSearch) {
            mPoiSearch = null;
        }
        super.onDestroy();
    }

    /**
     * 当定位成功需要做的事情
     */
    private void doWhenLocationSucess(double latitude, double longitude) {
        isSearchData = false;
        img_current_location.setSelected(true);
        getAddressInfoByLatLong(latitude, longitude);
        moveMapCamera(latitude, longitude);
        mAMap.invalidate();
    }

    /**
     * 移动动画
     */
    private void startTransAnimator() {
        if (null != mTransAnimator && !mTransAnimator.isRunning()) {
            mTransAnimator.start();
        }
    }

    /**
     * 把地图画面移动到定位地点(使用moveCamera方法没有动画效果)
     *
     * @param latitude
     * @param longitude
     */
    private void moveMapCamera(double latitude, double longitude) {
        if (null != mAMap) {
            mAMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude, longitude), zoom));
        }
    }

    /**
     * 开始进行poi搜索
     *
     * @param lpTemp
     */
    protected void doSearchQuery(LatLonPoint lpTemp) {
        mQuery = new PoiSearch.Query("", "", "");//第一个参数表示搜索字符串，第二个参数表示poi搜索类型，第三个参数表示poi搜索区域（空字符串代表全国）
        mQuery.setPageSize(20);// 设置每页最多返回多少条poiitem
        mQuery.setPageNum(searchNowPageNum);// 设置查第一页
        mPoiSearch = new PoiSearch(this, mQuery);
        mPoiSearch.setOnPoiSearchListener(mOnPoiSearchListener);
        if (lpTemp != null) {
            mPoiSearch.setBound(new PoiSearch.SearchBound(lpTemp, 500, true));//该范围的中心点-----半径，单位：米-----是否按照距离排序
        }
        mPoiSearch.searchPOIAsyn();// 异步搜索
    }

    /**
     * 通过经纬度获取当前地址详细信息，逆地址编码
     *
     * @param latitude
     * @param longitude
     */
    private void getAddressInfoByLatLong(double latitude, double longitude) {
        GeocodeSearch geocodeSearch = new GeocodeSearch(this);
        /*
        point - 要进行逆地理编码的地理坐标点。
        radius - 查找范围。默认值为1000，取值范围1-3000，单位米。
        latLonType - 输入参数坐标类型。包含GPS坐标和高德坐标。 可以参考RegeocodeQuery.setLatLonType(String)
        */
        RegeocodeQuery query = new RegeocodeQuery(new LatLonPoint(latitude, longitude), 500, GeocodeSearch.AMAP);
        geocodeSearch.getFromLocationAsyn(query);
        geocodeSearch.setOnGeocodeSearchListener(mOnGeocodeSearchListener);
    }

    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        try {
            if (null != aMapLocation) {
                stopLocation();
                if (aMapLocation.getErrorCode() == 0) {//可在其中解析amapLocation获取相应内容。
                    mLocation = aMapLocation;
                    mLatLng = new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude());
                    searchNowPageNum = 1;
                    MyLocationStyle myLocationStyle = new MyLocationStyle()
                            .myLocationIcon(BitmapDescriptorFactory
                                    .fromResource(R.drawable.ic_gps_point))
                            .strokeColor(Color.parseColor("#205eb9ff"))
                            .radiusFillColor(Color.parseColor("#205eb9ff"))
                            .myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW);
                    myLocationStyle.showMyLocation(true);
                    mAMap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style
                    mAMap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点，false表示隐藏定位蓝点并不进行定位，默认是false。
                    doWhenLocationSucess(aMapLocation.getLatitude(), aMapLocation.getLongitude());
                } else {
                    //定位失败时，可通过ErrCode（错误码）信息来确定失败的原因，errInfo是错误信息，详见错误码表。
                    Log.e("AmapError", "location Error, ErrCode:"
                            + aMapLocation.getErrorCode() + ", errInfo:"
                            + aMapLocation.getErrorInfo());
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    class onPoiSearchLintener implements PoiSearch.OnPoiSearchListener {

        @Override
        public void onPoiSearched(PoiResult result, int i) {
            if (srl_place_list != null) {
                srl_place_list.finishLoadMore();
            }
            if (i == 1000) {
                if (result != null && result.getQuery() != null) {// 搜索poi的结果
                    if (result.getQuery().equals(mQuery)) {// 是否是同一条
                        if (searchNowPageNum == 1) {
                            mPoiItems.clear();
                        }
                        mPoiItems.addAll(result.getPois());// 取得第一页的poiitem数据，页数从数字0开始
                        if (searchNowPageNum == 1 && !mPoiItems.isEmpty()) {
                            selectPoiItem = mPoiItems.get(0);
                        }
                        if (null != mRvAdapter) {
                            mRvAdapter.notifyDataSetChanged();
                        }
                        if (result.getPois().size() < 20) {
                            srl_place_list.setEnableLoadMore(false);
                        }
                        if (mPoiItems.size() == 0) {
                            ltp_address_date.setLoadingTip(LoadingTip.LoadStatus.empty);
                        } else {
                            ltp_address_date.setLoadingTip(LoadingTip.LoadStatus.finish);
                        }
                    }
                }
            }
        }

        @Override
        public void onPoiItemSearched(PoiItem poiItem, int i) {

        }
    }


    /**
     * 开始进行poi搜索
     */
    protected void doSearchQuery(String keyWord, String city, LatLonPoint lpTemp) {
        mQuery = new PoiSearch.Query(keyWord, "", city);//第一个参数表示搜索字符串，第二个参数表示poi搜索类型，第三个参数表示poi搜索区域（空字符串代表全国）
        mQuery.setPageSize(20);// 设置每页最多返回多少条poiitem
        mQuery.setPageNum(0);// 设置查第一页
        mPoiSearch = new PoiSearch(this, mQuery);
        mPoiSearch.setOnPoiSearchListener(mOnPoiSearchListener);
        if (lpTemp != null) {
            mPoiSearch.setBound(new PoiSearch.SearchBound(lpTemp, 500, true));//该范围的中心点-----半径，单位：米-----是否按照距离排序
        }
        mPoiSearch.searchPOIAsyn();// 异步搜索
    }
}
